package com.yanqu.road.server.manger.config;

import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.entity.config.beauty.BeautyIdentityInfo;
import com.yanqu.road.entity.config.beauty.BeautyInfo;
import com.yanqu.road.entity.config.beauty.BeautyRelation;
import com.yanqu.road.entity.config.beauty.BeautySkillInfo;
import com.yanqu.road.entity.config.promotion.ItemPeerlessPromotionInfo;
import com.yanqu.road.entity.config.promotion.PromotionInfo;
import com.yanqu.road.entity.config.skill.SkillInfo;
import com.yanqu.road.entity.config.skin.SkinInfo;
import com.yanqu.road.entity.enums.eSkillType;
import com.yanqu.road.entity.player.*;
import com.yanqu.road.logic.bussiness.config.BeautyBussiness;
import com.yanqu.road.logic.bussiness.player.UserBeautyBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.player.BeautyModule;
import com.yanqu.road.server.gameplayer.module.player.ChildModule;
import com.yanqu.road.server.gameplayer.module.skin.SkinModule;
import com.yanqu.road.server.logic.calc.CalculationManager;
import com.yanqu.road.server.logic.resource.GoodsResourceLogic;
import com.yanqu.road.server.manger.ConfigMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.manger.activity.curio.CurioMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

public class BeautyMgr extends TempMgr {

    private static Logger logger = LogManager.getLogger(BeautyMgr.class.getName());

    private static RandomHelper threadSafeRandom = new RandomHelper();

    private static Map<Integer, BeautyInfo> beautyInfoMap;

    private static Map<Integer, BeautyIdentityInfo> beautyIdentityInfoMap;

    private static Map<Integer, BeautySkillInfo> beautySkillInfoMap;

    private static List<BeautyRelation> beautyRelationList;

    private static int maxBeautyIdentityLv;

    public static String getBeautyResourceFlag(int beautyId) {
        BeautyInfo beautyInfo = getBeautyInfo(beautyId);
        return GoodsResourceLogic.getFlag(beautyInfo.getIcon(), beautyInfo.getSound(), beautyInfo.getAppearanceId());
    }

    public static String getBeautyTagFlag(int beautyId) {
        return "";
    }

    public static int getLinkType(int beautyId) {
        BeautyInfo beautyInfo = getBeautyInfo(beautyId);
        if (beautyInfo != null) {
            long linkAge = beautyInfo.getLinkAge();
            if (System.currentTimeMillis() < linkAge) {
                return 1;
            }
        }
        return 0;
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean stop() {
        return false;
    }

    @Override
    public boolean reloadConfig() {
        beautyInfoMap = BeautyBussiness.getBeautyInfoMap();
        beautyIdentityInfoMap = BeautyBussiness.getBeautyIdentityInfoMap();
        beautySkillInfoMap = BeautyBussiness.getBeautySkillInfoMap();
        beautyRelationList = BeautyBussiness.getBeautyRelationList();
        int maxLv = 0;
        for(BeautyIdentityInfo beautyIdentityInfo : beautyIdentityInfoMap.values()){
            if(beautyIdentityInfo.getIdentityLv() > maxLv){
                maxLv = beautyIdentityInfo.getIdentityLv();
            }
        }
        maxBeautyIdentityLv = maxLv;
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    public static Map<Integer, BeautySkillInfo> getBeautySkillInfoMap() {
        return beautySkillInfoMap;
    }

    public static BeautySkillInfo getBeautySkillInfo(int skillPos){
        return beautySkillInfoMap.get(skillPos);
    }

    public static Map<Integer, BeautyInfo> getBeautyInfoMap() {
        return beautyInfoMap;
    }

    public static int getRandomSkillValue(boolean isCustom){
        List<Integer> weightList;
        if(isCustom){//是否定制
            weightList = ConfigMgr.getBeautySkillCustomModifyParamList();
        }else {
            weightList = ConfigMgr.getBeautySkillNormalModifyParamList();
        }
        int sumWeight = 0;
        for(int weight : weightList){
            sumWeight += weight;
        }
        int randomValue = threadSafeRandom.next(0, sumWeight);
        int tempWeight = 0;
        for(int i = 0; i < weightList.size(); i++){
            int weight = weightList.get(i);
            tempWeight += weight;
            if(tempWeight > randomValue){
                return i + 1;
            }
        }
        return 0;
    }

    public static BeautyIdentityInfo getBeautyIdentityInfo(int identityLv) {
        return beautyIdentityInfoMap.get(identityLv);
    }

    /**
     * 获得美名等级之前所有的配置
     * @param identityLv
     * @return
     */
    public static List<BeautyIdentityInfo> getBeautyIdentityInfoListLessThenLv(int identityLv) {
        List<BeautyIdentityInfo> list = new ArrayList<>();
        for (BeautyIdentityInfo beautyIdentityInfo : beautyIdentityInfoMap.values()) {
            if (beautyIdentityInfo.getIdentityLv() <= identityLv){
                list.add(beautyIdentityInfo);
            }
        }
        return list;
    }

    public static BeautyInfo getBeautyInfo(int beautyId) {
        return beautyInfoMap.get(beautyId);
    }

    public static boolean beautyAndPatronsHasRelation(UserBeauty userBeauty, UserPatrons patrons){
        //自选缘分门客
        if (userBeauty.getSelfSelectPatronsMap() != null) {
            for (BeautySelfSelectPatronsPosition position : userBeauty.getSelfSelectPatronsMap().values()) {
                if (position.getPatronsId() > 0 && position.getPatronsId() == patrons.getPatronsId()) {
                    return true;
                }
            }
        }
        //配置缘分门客
        if (userBeauty.getOriRelationPatronsId().contains(patrons.getPatronsId())) {
            return true;
        }
        if(null != beautyRelationList){
            return beautyRelationList.stream().anyMatch(relation -> {
                if (relation.getBeautyId() == userBeauty.getBeautyId() && relation.getPatronsId() == patrons.getPatronsId()) {
                    if (checkRelationCondition(relation, userBeauty, patrons)) {
                        userBeauty.getOriRelationPatronsId().add(patrons.getPatronsId());
                        return true;
                    }
                }
                return false;
            });
        }
        return false;
    }

    public static boolean checkRelationCondition(UserBeauty userBeauty, UserPatrons patrons) {
        if(null != beautyRelationList){
            for (BeautyRelation relation : beautyRelationList) {
                if(checkRelationCondition(relation, userBeauty, patrons)){
                    return true;
                }
            }
        }
        return false;
    }

    public static boolean checkRelationCondition(BeautyRelation relation, UserBeauty userBeauty, UserPatrons patrons) {
        if (patrons == null) {
            return false;
        }
        if (patrons.getPatronsId() != relation.getPatronsId()) {
            return false;
        }
        if(userBeauty.getBeautyId() != relation.getBeautyId()){
            return false;
        }
        if (Objects.equals("0", relation.getGetCondition())) {
            return true;
        }
        List<Integer> conditionList = StringUtils.stringToIntegerList(relation.getGetCondition(), "=");
        if(conditionList.size() < 2){
            return false;
        }
        int type = conditionList.get(0);
        if(type == 2){
            //type = 2 美女晋升条件
            int targetPromotion = conditionList.get(1);
            if(userBeauty.getQualityPromotionId() >= targetPromotion){
                return true;
            }
        } else if (type == 1) {
            //目前只有type1  门客晋升
            int targetPromotion = conditionList.get(1);
            if (patrons.getShowPromotionId() >= targetPromotion) {
                return true;
            }
        }
        return false;
    }

    /**
     * 不判断晋升关系 passCondition
     */
    public static boolean beautyAndPatronsHasRelationNotCondition(UserBeauty userBeauty, UserPatrons patrons){
        //自选缘分门客
        if (userBeauty.getSelfSelectPatronsMap() != null) {
            for (BeautySelfSelectPatronsPosition position : userBeauty.getSelfSelectPatronsMap().values()) {
                if (position.getPatronsId() > 0 && position.getPatronsId() == patrons.getPatronsId()) {
                    return true;
                }
            }
        }
        //配置缘分门客
        if(null != beautyRelationList){
            return beautyRelationList.stream().anyMatch(relation -> {
                if (relation.getBeautyId() == userBeauty.getBeautyId() && relation.getPatronsId() == patrons.getPatronsId()) {
                    return true;
                }
                return false;
            });
        }
        return false;
    }

    //不可使用，仅后台统计用
    public static List<Integer> getBeautyRelation(UserPatrons patrons){
        List<Integer> dataList = new ArrayList<>();
        for(BeautyRelation beautyRelation : beautyRelationList){
            if(beautyRelation.getPatronsId() == patrons.getPatronsId() && beautyRelation.passCondition(patrons)){
                if(!dataList.contains(beautyRelation.getBeautyId())){
                    dataList.add(beautyRelation.getBeautyId());
                }
            }
        }
        return dataList;
    }

    /**
     * 获取门客对应美女关系，不判断晋升
     * @param patronsId
     * @return
     */
    public static List<BeautyRelation> getBeautyRelationListByPatronsId(int patronsId){
        List<BeautyRelation> list = new ArrayList<>();
        for(BeautyRelation beautyRelation : beautyRelationList){
            if(beautyRelation.getPatronsId() == patronsId){
                list.add(beautyRelation);
            }
        }
        return list;
    }

    public static long getBeautyQualification(UserBeauty userBeauty) {
        if(null == userBeauty){
            return 0;
        }
        BeautyInfo beautyInfo = getBeautyInfo(userBeauty.getBeautyId());
        long qualification = 0;
        if(null != beautyInfo){
            qualification = beautyInfo.getQualification();
            qualification = qualification + (beautyInfo.getAddQualification() * (userBeauty.getLevel() -1));
        }
        if(qualification < 0){
            qualification = 0;
        }
        return qualification;
    }

    public static boolean isUserBeautyExist(UserBeauty userBeauty) {
        return null != userBeauty;
    }

    //在輸出白的1.美女传唤
    public static int getAddBeautyExp(GamePlayer player, UserBeauty userBeauty) {
        double skillAddition = player.getModule(BeautyModule.class).getIdentitySkillAddition(eSkillType.BeautyExp.getValue(), 0);
        BeautyInfo beautyInfo = BeautyMgr.getBeautyInfo(userBeauty.getBeautyId());
        skillAddition += player.getModule(PatronsModule.class).getTalentSkillAddition(eSkillType.BeautyTrystAddBeautyExp.getValue(), beautyInfo.getOccupation());
        skillAddition += CurioMgr.getSkillAdditionBySkillType(eSkillType.CurioBeautyTalkExpSkill.getValue(), player, beautyInfo.getOccupation());
        double value1 = Math.pow(userBeauty.getTotalGlamour(), (double)ConfigMgr.getBeautyAddExpParam1() / 1000);
        double addExp = value1 / (userBeauty.getTotalGlamour() + ConfigMgr.getBeautyAddExpParam2()) * ConfigMgr.getBeautyAddExpParam3() / 1000;
        addExp = Math.ceil(addExp * (skillAddition / 1000 + 1));
        return (int) addExp;
    }

    public static BigInteger getModifySkillCost(int times){
        BigDecimal value1 = BigDecimal.valueOf((double) ConfigMgr.getBeautySkillModifySilverCostParam1() / 1000);
        BigDecimal value2 = BigDecimal.valueOf(Math.pow(ConfigMgr.getBeautySkillModifySilverCostParam2() + times, 4));
        BigDecimal value3 = BigDecimal.valueOf((double) ConfigMgr.getBeautySkillModifySilverCostParam3() / 1000);
        BigDecimal value4 = BigDecimal.valueOf(Math.pow((double)ConfigMgr.getBeautySkillModifySilverCostParam4() /1000, times - 1));
        return value1.multiply(value2).add(value3.multiply(value4)).setScale(0, BigDecimal.ROUND_UP).toBigInteger();
    }

    /**
     * 是否产生子嗣
     */
    public static boolean isTrystMakeChild(GamePlayer player) {
        int remainingSite = player.getModule(ChildModule.class).getRemainingChildSiteCount();
        int totalSite = player.getModule(ChildModule.class).getChildSiteCount();
        if (remainingSite > 0) {
            int randomValue = threadSafeRandom.next(0, 1000);
            int weight;
            BeautyModule beautyModule = player.getModule(BeautyModule.class);
            long totalTrystTimes = getTotalTrystTimes(beautyModule.getBeautyMap());
            if(totalTrystTimes < GameConfig.BEAUTY_TRYST_MAKE_CHILD_TIMES -1){//第1次不生孩子
                return false;
            }else if(totalTrystTimes == GameConfig.BEAUTY_TRYST_MAKE_CHILD_TIMES -1){//第2次生
                return true;
            }else if(totalTrystTimes > ConfigMgr.getBeautyTrystMakeChildParam1()) {
                weight = ConfigMgr.getBeautyTrystMakeChildParam5() + totalSite * ConfigMgr.getBeautyTrystMakeChildParam6();
                return weight > randomValue;
            }else {
                int noMakeTimes = beautyModule.getNoMakeChildTimes();
                boolean result;
                if(0 == noMakeTimes) {
                    weight = ConfigMgr.getBeautyTrystMakeChildParam2();
                }else if(1 == noMakeTimes) {
                    weight = ConfigMgr.getBeautyTrystMakeChildParam3();
                }else {
                    weight = ConfigMgr.getBeautyTrystMakeChildParam4();
                }
                result = weight > randomValue;
                if(result){
                    beautyModule.resetNoMakeChildTimes();
                }else {
                    beautyModule.addNoMakeChildTimes();
                }
                return result;
            }
        }
        return false;
    }

    /**
     * 总传唤次数
     */
    public static long getTotalTrystTimes(Map<Integer, UserBeauty> userBeautyMap){
        long times = 0;
        if(null != userBeautyMap){
            for(UserBeauty userBeauty : userBeautyMap.values()){
                if(isUserBeautyExist(userBeauty)){
                    times += userBeauty.getTotalTrystTimes();
                }
            }
        }
        return times;
    }

    /**
     * 总子嗣数量
     */
    public static long getTotalChildCount(Map<Integer, UserBeauty> userBeautyMap){
        long count = 0;
        if(null != userBeautyMap){
            for(UserBeauty userBeauty : userBeautyMap.values()){
                if(isUserBeautyExist(userBeauty)){
                    count += userBeauty.getChildCount();
                }
            }
        }
        return count;
    }

    /**
     * 总赏赐次数
     */
    public static long getTotalRewardTimes(Map<Integer, UserBeauty> userBeautyMap){
        long times = 0;
        if(null != userBeautyMap){
            for(UserBeauty userBeauty : userBeautyMap.values()){
                if(isUserBeautyExist(userBeauty)){
                    times += userBeauty.getTotalRewardTimes();
                }
            }
        }
        return times;
    }

    /**
     * 总出游次数
     */
    public static long getTotalTravelTimes(Map<Integer, UserBeauty> userBeautyMap){
        long times = 0;
        if(null != userBeautyMap){
            for(UserBeauty userBeauty : userBeautyMap.values()){
                if(isUserBeautyExist(userBeauty)){
                    times += userBeauty.getTravelTimes();
                }
            }
        }
        return times;
    }

    /**
     * 总宠幸次数
     */
    public static long getTotalFavorTimes(Map<Integer, UserBeauty> userBeautyMap){
        long times = 0;
        if(null != userBeautyMap){
            for(UserBeauty userBeauty : userBeautyMap.values()){
                if(isUserBeautyExist(userBeauty)){
                    times += userBeauty.getTravelTimes();
                    times += userBeauty.getBathTimes();
                }
            }
        }
        return times;
    }

    /**
     * 总洗澡次数
     */
    public static long getTotalBathTimes(Map<Integer, UserBeauty> userBeautyMap){
        long times = 0;
        if(null != userBeautyMap){
            for(UserBeauty userBeauty : userBeautyMap.values()){
                if(isUserBeautyExist(userBeauty)){
                    times += userBeauty.getBathTimes();
                }
            }
        }
        return times;
    }

    /**
     * 总美女数量
     */
    public static long getTotalBeautyCount(Map<Integer, UserBeauty> userBeautyMap){
        long count = 0;
        if(null != userBeautyMap){
            for(UserBeauty userBeauty : userBeautyMap.values()){
                if(isUserBeautyExist(userBeauty)){
                    count++;
                }
            }
        }
        return count;
    }

    public static long getTotalIntimacy(Map<Integer, UserBeauty> userBeautyMap){
        long intimacy = 0;
        if(null != userBeautyMap){
            for(UserBeauty userBeauty : userBeautyMap.values()){
                if(isUserBeautyExist(userBeauty)){
                    intimacy += userBeauty.getTotalIntimacy();
                }
            }
        }
        return intimacy;
    }

    public static long getTotalGlamour(Map<Integer, UserBeauty> userBeautyMap){
        long glamour = 0;
        if(null != userBeautyMap){
            for(UserBeauty userBeauty : userBeautyMap.values()){
                if(isUserBeautyExist(userBeauty)){
                    glamour += userBeauty.getTotalGlamour();
                }
            }
        }
        return glamour;
    }

    public static int getMaxBeautyIdentityLv() {
        return maxBeautyIdentityLv;
    }

    public static boolean isIdentitySkillUpgrade(UserBeauty userBeauty){
        int oldIdentitySkillLv = userBeauty.getIdentitySkillLv();
        BeautyInfo beautyInfo = getBeautyInfo(userBeauty.getBeautyId());
        List<Integer> upgradeList = beautyInfo.getIdentitySkillUpgradeMarkList();
        int level = 1;
        for(int i = 0; i < upgradeList.size(); i++){
            if(1 == upgradeList.get(i)){
                level++;
            }
            if(i >= userBeauty.getIdentityLv() - 1){
                break;
            }
        }
        if(level != oldIdentitySkillLv){
            userBeauty.setIdentitySkillLv(level);
            return true;
        }
        return false;
    }

    //根據鎂鋁洗澡次數返回對應需要的元寶
    public static int getTravelCost(int times){
        List<Integer> travelCostParams = StringUtils.stringToIntegerList(GameConfig.BEAUTY_FAVOR_TRAVEL_COST, "\\|");
        if(travelCostParams.size() != 3){
            return 99999999;
        }
        int cost = travelCostParams.get(0);
        if(times > 0){
            for(int i = 0;i < times;i++){
                cost += travelCostParams.get(1);
            }
        }
        if(cost > travelCostParams.get(2)){
            cost = travelCostParams.get(2);
        }
        return cost;
    }

    public static int getBeautyIntimacyByQuality(int quality){
        for(BeautyInfo beautyInfo : beautyInfoMap.values()){
            if(beautyInfo.getQuality() == quality){
                return beautyInfo.getInitIntimacy();
            }
        }
        return 0;
    }


    public static String getUserBeautyDetailInfoJsonStr(long userId, int patronsId) {
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        Map<Integer, UserBeauty> userBeautyMap;
        if (player != null) { //在线
            userBeautyMap = player.getModule(BeautyModule.class).getUserBeautyMap();
        } else { //离线
            userBeautyMap = UserBeautyBussiness.getUserBeautyAndSkillMap(userId);

            try {
                //指定国内渠道屏蔽同时拥有美女103001和103209的,屏蔽103209
                int channelId = ServerListMgr.getChannelId(GameServer.getInstance().getServerId());
                if (
                        channelId == 201 ||
                        channelId == 221 ||
                        channelId == 231 ||
                        channelId == 241 ||
                        channelId == 301 ||
                        channelId == 311 ||
                        channelId == 321) {
                    if (userBeautyMap.containsKey(103001)) {
                        userBeautyMap.remove(103209);
                    }
                }
            } catch (Exception e) {
                logger.error(e);
            }
        }
        return parseBeautyDetailInfoJsonStr(userBeautyMap.get(patronsId));
    }


    public static String parseBeautyDetailInfoJsonStr(UserBeauty userBeauty) {
        JSONObject jsonObject = new JSONObject();
        try {
            if (userBeauty != null) {
                jsonObject.put("id", userBeauty.getBeautyId());
                jsonObject.put("level", userBeauty.getLevel());
                jsonObject.put("skinId", userBeauty.getSkinId());
                jsonObject.put("glamour", userBeauty.getTotalGlamour());
                jsonObject.put("intimacy", userBeauty.getTotalIntimacy());
                jsonObject.put("quality", userBeauty.getQuality());
                jsonObject.put("identityLv", userBeauty.getIdentityLv());
                jsonObject.put("identitySkillLv", userBeauty.getIdentitySkillLv());

                jsonObject.put("skill1", userBeauty.getSkill1());
                jsonObject.put("skill12", userBeauty.getSkill2());
                jsonObject.put("escortSkill1", userBeauty.getEscortSkill1());
                jsonObject.put("escortSkill2", userBeauty.getEscortSkill2());

                jsonObject.put("skinSkill1", userBeauty.getSkinSkill1());
                jsonObject.put("skinSkill2", userBeauty.getSkinSkill2());
                jsonObject.put("genderSwapMark", userBeauty.getGenderSwapMark());

                Map<Integer, Integer> skillSumMap = new HashMap<>();
                //商铺技能
                for (Map.Entry<Integer, UserBeautySkill> skillEntry : userBeauty.getSkillMap().entrySet()) {
                    UserBeautySkill skill = skillEntry.getValue();
                    int occupation = skill.getSkillPos() % 5;
                    int sum = skillSumMap.getOrDefault(occupation, 0);
                    sum += skill.getSkillValue();
                    skillSumMap.put(occupation, sum);
                }
                for (Map.Entry<Integer, Integer> entry : skillSumMap.entrySet()) {
                    jsonObject.put("occupation-" + entry.getKey(), entry.getValue());
                }

                jsonObject.put("peerlessUp", userBeauty.getPeerlessUp());
                jsonObject.put("peerlessSkills", JSONObject.toJSONString(userBeauty.getPeerlessSkillMap().values()));
                jsonObject.put("musicRoomSkills", PropertyHelper.parsePropertyToString(userBeauty.getMusicRoomSkill()));
                jsonObject.put("travelBookAlbumSkill", userBeauty.getAlbumSkillMapStr()); // 旅行册卡册技能
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return jsonObject.toString();
    }

    /**
     * 美女无双技能提升给效果=addtition*(1+b/1000)
     *
     * @param beauty
     * @param userPatrons
     * @return
     */
    public static BigDecimal getBeautyPeerlessSkillAddition(BigDecimal addtition, UserBeauty beauty, UserPatrons userPatrons) {
        if (null == beauty || null == userPatrons) {
            return addtition;
        }
        //无双技能提升效果=1+b/1000
        int peerlessPercentage = 0;
        for (BeautyPeerlessSkillInfo peerlessSkillInfo : beauty.getPeerlessSkillMap().values()) {
            SkillInfo skillInfo = getPeerlessSkill(beauty, peerlessSkillInfo.getId());
            if (null == skillInfo) {
                continue;
            }
            if (peerlessSkillInfo.getPatronsId() == userPatrons.getPatronsId()) {
                int peerlessSkillLevel = peerlessSkillInfo.getLevel();
                peerlessPercentage += SkillMgr.getSkillAddition(skillInfo, peerlessSkillLevel);
            }
        }
        BigDecimal result = addtition.multiply(BigDecimal.valueOf(peerlessPercentage).divide(BigDecimal.valueOf(1000))).setScale(0, BigDecimal.ROUND_UP);
        return result;
    }

    /**
     * 美女对门客的不包含无双部分的加成
     */
    public static BigDecimal calcBeautyRelationPatronsAddAbilityExcludePeerless(UserPatrons userPatrons, UserBeauty userBeauty, BigDecimal baseAbility, BigDecimal calcAbilityParam, BigDecimal abilityAdditionRatio) {
        BigDecimal totalAddition = BigDecimal.ZERO;
        if (!BeautyMgr.beautyAndPatronsHasRelation(userBeauty, userPatrons)) {
            return totalAddition;
        }
        //魅力值技能
        int level1 = userBeauty.getSkill1();
        List<Integer> beautySkillList = StringUtils.stringToIntegerList(GameConfig.BEAUTY_PATRONS_SKILL, "\\|");
        SkillInfo skillInfo1 = SkillMgr.getSkillInfo(beautySkillList.get(0));
        BigDecimal skillAddition1 = BigDecimal.valueOf(SkillMgr.getSkillAddition(skillInfo1, level1));
        int level2 = userBeauty.getSkill2();
        SkillInfo skillInfo2 = SkillMgr.getSkillInfo(beautySkillList.get(1));
        BigDecimal skillAddition2 = BigDecimal.valueOf((double) SkillMgr.getSkillAddition(skillInfo2, level2) / 1000)
                .setScale(CalculationManager.CALCULATION_SCALE, BigDecimal.ROUND_UP)
                .multiply(baseAbility)
                .setScale(CalculationManager.CALCULATION_SCALE, BigDecimal.ROUND_UP);

        //押镖技能
        int escortSkillLevel1 = userBeauty.getEscortSkill1();
        List<Integer> escortSkill1 = StringUtils.stringToIntegerList(GameConfig.BEAUTY_ESCORT_PATRONS_SKILL, "\\|");
        SkillInfo skillInfo = SkillMgr.getSkillInfo(escortSkill1.get(0));
        BigDecimal escortSkill1Addition = BigDecimal.valueOf(SkillMgr.getSkillAddition(skillInfo, escortSkillLevel1));

        int escortSkillLevel2 = userBeauty.getEscortSkill2();
        List<Integer> escortSkill2 = StringUtils.stringToIntegerList(GameConfig.BEAUTY_ESCORT_PATRONS_SKILL, "\\|");
        SkillInfo escortSkill2Info2 = SkillMgr.getSkillInfo(escortSkill2.get(1));
        BigDecimal escortSkill2Addition = BigDecimal.valueOf(SkillMgr.getSkillAddition(escortSkill2Info2, escortSkillLevel2))
                .multiply(calcAbilityParam)
                .multiply(BigDecimal.ONE.add(abilityAdditionRatio))
                .setScale(CalculationManager.CALCULATION_SCALE, BigDecimal.ROUND_UP);
        totalAddition = skillAddition1.add(skillAddition2).add(escortSkill1Addition).add(escortSkill2Addition);

        //妙音坊技能
        BigDecimal musicRoomAddition = BigDecimal.ZERO;
        for (Map.Entry<Integer, BigInteger> entry : userBeauty.getMusicRoomSkill().getGoods().entrySet()) {
            int skillId = entry.getKey();
            int skillLv = entry.getValue().intValue();
            SkillInfo musicRoomSkillInfo = SkillMgr.getSkillInfo(skillId);
            if (musicRoomSkillInfo == null) {
                continue;
            }
            int skillAddition = SkillMgr.getSkillAddition(musicRoomSkillInfo, skillLv);
            if (musicRoomSkillInfo.getType() == eSkillType.BeautyPatronsEscortSkill1.getValue()){
                //加固定值
                musicRoomAddition = musicRoomAddition.add(BigDecimal.valueOf(skillAddition));
            } else if (musicRoomSkillInfo.getType() == eSkillType.BeautyPatronsSkill2.getValue()){
                //加百分比
                BigDecimal addition = BigDecimal.valueOf((double) skillAddition / 1000)
                        .setScale(CalculationManager.CALCULATION_SCALE, BigDecimal.ROUND_UP)
                        .multiply(baseAbility)
                        .setScale(CalculationManager.CALCULATION_SCALE, BigDecimal.ROUND_UP);
                musicRoomAddition = musicRoomAddition.add(addition);
            } else if (musicRoomSkillInfo.getType() == eSkillType.BeautyPatronsEscortSkill2.getValue()){
                //加资质
                BigDecimal addition = BigDecimal.valueOf(skillAddition)
                        .multiply(calcAbilityParam)
                        .multiply(BigDecimal.ONE.add(abilityAdditionRatio))
                        .setScale(CalculationManager.CALCULATION_SCALE, BigDecimal.ROUND_UP);
                musicRoomAddition = musicRoomAddition.add(addition);
            }
        }
        totalAddition = totalAddition.add(musicRoomAddition);
        totalAddition = totalAddition.setScale(0, BigDecimal.ROUND_UP);//和客户端同步,每个孔都要单独向上取整
        return totalAddition;
    }

    /**
     * 美女对门客的有包含无双部分的加成
     * @param baseAbility 门客总资质乘每点资质基础赚钱的值
     * @param calcAbilityParam 每点资质基础赚钱
     * @param abilityAdditionRatio 总加成千分比
     */
    public static BigDecimal calcBeautyRelationPatronsAddAbilityIncludePeerless(UserPatrons userPatrons, UserBeauty userBeauty, BigDecimal baseAbility, BigDecimal calcAbilityParam, BigDecimal abilityAdditionRatio) {
        BigDecimal totalAddition = calcBeautyRelationPatronsAddAbilityExcludePeerless(userPatrons, userBeauty, baseAbility, calcAbilityParam, abilityAdditionRatio);
        if (totalAddition.compareTo(BigDecimal.ZERO) != 0 && userBeauty.getPeerlessUp() > 0) {
            BigDecimal additionByPeerlessSkill = BeautyMgr.getBeautyPeerlessSkillAddition(totalAddition,
                    userBeauty, userPatrons);

            totalAddition = totalAddition.add(additionByPeerlessSkill);
        }
        return totalAddition;
    }

    /**
     * 美女无双技能提升给效果=addtition*(1+b/1000)
     * @param baseAbility 门客总资质乘每点资质基础赚钱的值
     * @param calcAbilityParam 每点资质基础赚钱
     * @param abilityAdditionRatio 总加成千分比
     */
    public static BigDecimal getAllBeautyPeerlessSkillAddition(UserPatrons userPatrons, Map<Integer, UserBeauty> beautyMap, BigDecimal baseAbility, BigDecimal calcAbilityParam, BigDecimal abilityAdditionRatio) {
        BigDecimal totalPeerlessAddition = BigDecimal.ZERO;
        for (UserBeauty beauty : beautyMap.values()) {
            if (BeautyMgr.beautyAndPatronsHasRelation(beauty, userPatrons) && beauty.getPeerlessUp() > 0) {//美女关系

                BigDecimal totalAddition = calcBeautyRelationPatronsAddAbilityExcludePeerless(userPatrons, beauty, baseAbility, calcAbilityParam, abilityAdditionRatio);

                BigDecimal additionByPeerlessSkill = BeautyMgr.getBeautyPeerlessSkillAddition(totalAddition,
                        beauty, userPatrons);

                totalPeerlessAddition = totalPeerlessAddition.add(additionByPeerlessSkill);
            }
        }
        return totalPeerlessAddition;
    }

    public static SkillInfo getPeerlessSkill(UserBeauty userBeauty, int position) {
        PromotionInfo resultPromotion = getPeerlessSkillPromotion(userBeauty, position);
        if (null == resultPromotion) {
            return null;
        }
        int skillId = resultPromotion.getPeerlessSkillId();

        return SkillMgr.getSkillInfo(skillId);
    }

    public static PromotionInfo getPeerlessSkillPromotion(UserBeauty userBeauty, int position) {
        List<PromotionInfo> listPromotion = PromotionMgr.getCharacterPromotion(userBeauty.getBeautyId());
        if (null == listPromotion) {
            return null;
        }
        PromotionInfo startPromotionInfo = null;
        for (PromotionInfo promotionInfo : listPromotion) {
            if (promotionInfo.getType() == 11 || promotionInfo.getType() == 13) {//无双晋升类型11、13
                startPromotionInfo = promotionInfo;
                break;
            }
        }

        if (null == startPromotionInfo) {
            return null;
        }
        PromotionInfo nextPromotionInfo = startPromotionInfo;
        List<PromotionInfo> unlockPromotions = new ArrayList<>();
        unlockPromotions.add(startPromotionInfo);
        int promotionAmount = userBeauty.getPeerlessUp();
        for (int i = 0; i < promotionAmount; i++) {
            nextPromotionInfo = PromotionMgr.getPromotionInfoById(nextPromotionInfo.getNextId());
            unlockPromotions.add(nextPromotionInfo);
        }

        if (position > unlockPromotions.size() || position <= 0) {
            return null;
        }

        PromotionInfo resultPromotion = unlockPromotions.get(position - 1);
        return resultPromotion;
    }

    public static boolean checkPeerlessSkillUpgradeEnough(GamePlayer player, UserBeauty beauty, int position) {
        PromotionInfo resultPromotion = getPeerlessSkillPromotion(beauty, position);
        if (null == resultPromotion) {
            return false;
        }
        BeautyPeerlessSkillInfo peerlessSkillInfo = beauty.getPeerlessSkill(position);
        if (null == peerlessSkillInfo) {
            return false;
        }
        if (resultPromotion.getType() == 11) {
            String[] arrStrs = resultPromotion.getParamList().split("=");
            String[] levelUpStrs = arrStrs[2].split("#");

            if (levelUpStrs.length < peerlessSkillInfo.getLevel()) {
                return false;
            }
            String[] promotionStrs = levelUpStrs[peerlessSkillInfo.getLevel() - 1].split("\\|");
            if (promotionStrs.length != 2) {
                return false;
            }

            String[] peerlessAttrs = promotionStrs[0].split(";");
            if (peerlessAttrs.length != 2) {
                return false;
            }
            String[] normalAttrs = promotionStrs[1].split(";");
            if (normalAttrs.length != 2) {
                return false;
            }

            //需要无双皮数量
            int peerlessSkinNeed = Integer.valueOf(peerlessAttrs[0]);
            //需要无双皮等级
            int peerlessSkinLevel = Integer.valueOf(peerlessAttrs[1]);

            //普通皮数量
            int normalSkinNeed = Integer.valueOf(normalAttrs[0]);
            int normalSkinLevel = Integer.valueOf(normalAttrs[1]);

            List<UserSkin> skinList = player.getModule(SkinModule.class).getUserSkinListByBeautyId(beauty.getBeautyId());
            for (UserSkin userSkin : skinList) {
                SkinInfo skinInfo = SkinMgr.getSkinInfo(userSkin.getSkinId());
                if (null == skinInfo) {
                    continue;
                }
                if (skinInfo.isPeerless() == 1) {
                    if (userSkin.getLevel() >= peerlessSkinLevel && peerlessSkinNeed > 0) {
                        peerlessSkinNeed--;
                    }
                } else {
                    if (userSkin.getLevel() >= normalSkinLevel && normalSkinNeed > 0) {
                        normalSkinNeed--;
                    }
                }
            }

            if (peerlessSkinNeed != 0 || normalSkinNeed != 0) {//皮肤要求不满足
                return false;
            }
        } else if (resultPromotion.getType() == 13) {
            //        13 美女晋升无双渠道
            //        晋升技能；缘定三生|缘定三生等级；缘定三生等级；缘定三生等级；缘定三生等级；缘定三生等级
            ItemPeerlessPromotionInfo itemPeerlessPromotionInfo = resultPromotion.getItemPeerlessPromotionInfo();
            if (itemPeerlessPromotionInfo == null) {
                return false;
            }

            if (peerlessSkillInfo.getLevel() >= itemPeerlessPromotionInfo.getLevelNeed().size()) {
                // 满级了
                return false;
            }

            int needSkillNum = position;
            int needLv = itemPeerlessPromotionInfo.getPeerlessSkillLvUpNeedPromotionSkillLv(peerlessSkillInfo.getLevel() + 1);

            for (int pos = 1; pos <= itemPeerlessPromotionInfo.getPromotionSkills().size(); pos++) {
                int promoteSkillLevelByPos = beauty.getPromoteSkillLevelByPos(pos);
                if (promoteSkillLevelByPos >= needLv) {
                    needSkillNum --;
                }
            }
            if (needSkillNum > 0) {//晋升技能等级要求不满足
                return false;
            }
        }

        return true;

    }

    /**
    * 描述：获取同形象美女切换编号
    * 作者：zrq
    * 时间：2023/3/15
    * 参数：

    * 返回值：
    **/
    public static int getGenderSwapId(UserBeauty userBeauty){
        if(null == userBeauty){
            return 0;
        }
        if(userBeauty.getGenderSwapMark() == 0){
            return userBeauty.getBeautyId();
        }else {
            BeautyInfo beautyInfo = getBeautyInfo(userBeauty.getBeautyId());
            if(null == beautyInfo){
                return userBeauty.getBeautyId();
            }
            if(beautyInfo.getGenderSwapId() > 0){
                return beautyInfo.getGenderSwapId();
            }else {
                return userBeauty.getBeautyId();
            }
        }
    }

    public static List<BeautyRelation> getBeautyRelationListByPromotion(int type, int promotion){
        List<BeautyRelation> result = new ArrayList<>();
        for (BeautyRelation relation : beautyRelationList) {
           if("0".equals(relation.getGetCondition())){
               continue;
           }
           List<Integer> conditionList = StringUtils.stringToIntegerList(relation.getGetCondition(), "=");
           if(conditionList.size() != 2){
               continue;
           }
           int targetType = conditionList.get(0);
           int targetPromotion = conditionList.get(1);
           if(type == targetType && promotion == targetPromotion){
               result.add(relation);
           }
        }
        return result;
    }


    /**
     * 晋升技能提升的效果
     *
     * @param userBeauty 美女数据
     * @param skillType  技能类型
     * @param addType    加成类型 1亲密 2魅力
     */
    public static int getPromotionSkillAddition(UserBeauty userBeauty, int skillType, int addType) {
        int addition = 0;
        BeautyInfo beautyInfo = getBeautyInfo(userBeauty.getBeautyId());
        if (beautyInfo == null) {
            // 没得加成
            return 0;
        }

        List<PromotionInfo> listPromotion = PromotionMgr.getCharacterPromotion(userBeauty.getBeautyId());
        if (null == listPromotion || listPromotion.isEmpty()) {
            return 0;
        }

        PromotionInfo startPromotionInfo = null;
        for (PromotionInfo promotionInfo : listPromotion) {
            if (promotionInfo.getType() == 11 || promotionInfo.getType() == 13) {//无双晋升类型11、13
                startPromotionInfo = promotionInfo;
                break;
            }
        }

        ItemPeerlessPromotionInfo itemPeerlessPromotionInfo = startPromotionInfo.getItemPeerlessPromotionInfo();
        if (itemPeerlessPromotionInfo == null) {
            return 0;
        }

        for (int pos = 1; pos <= itemPeerlessPromotionInfo.getPromotionSkills().size(); pos++) {
            int promotionSkillId = itemPeerlessPromotionInfo.getPromotionSkills().get(pos - 1);
            if (promotionSkillId == 0) {
                continue;
            }
            SkillInfo skillInfo = SkillMgr.getSkillInfo(promotionSkillId);
            if (skillInfo == null) {
                // 没得技能
                continue;
            }
            if (userBeauty.getPromoteSkillLevelByPos(pos) == 0) {
                // 没等级
                continue;
            }
            if (skillInfo.getType() == skillType) {
                if (addType == 1) {
                    // 亲密加成
                    addition += skillInfo.getParamList().get(0) + (skillInfo.getUpgradeParamList().get(0) * (userBeauty.getPromoteSkillLevelByPos(pos) - 1));
                } else if (addType == 2) {
                    // 魅力加成
                    addition += skillInfo.getParamList().get(1) + (skillInfo.getUpgradeParamList().get(1) * (userBeauty.getPromoteSkillLevelByPos(pos) - 1));
                }
            }

        }
        return addition;
    }

    /**
     * 获取美女的晋升技能id
     */
    public static int getPromotionSkillId(int beautyId, int pos) {
        BeautyInfo beautyInfo = getBeautyInfo(beautyId);
        if (beautyInfo == null) {
            return 0;
        }
        List<PromotionInfo> listPromotion = PromotionMgr.getCharacterPromotion(beautyId);
        if (null == listPromotion || listPromotion.isEmpty()) {
            return 0;
        }
        ItemPeerlessPromotionInfo itemPeerlessPromotionInfo = listPromotion.get(0).getItemPeerlessPromotionInfo();
        if (itemPeerlessPromotionInfo == null) {
            return 0;
        }
        return itemPeerlessPromotionInfo.getPromotionSkillId(pos);
    }

    /**
     * 获得美女所有的缘分门客加成总和
     * @param userBeauty
     * @return
     */
    public static BigDecimal calcBeautyTotalAddRelationPatronsAbility(UserBeauty userBeauty, CalcPatronsAbilityParam param) {
        Map<Integer, UserPatrons> patronsMap = param.getPatronsMap();
        BigDecimal totalAddition = BigDecimal.ZERO;
        for (UserPatrons userPatrons : patronsMap.values()) {
            if (beautyAndPatronsHasRelation(userBeauty, userPatrons)) {
//                PatronsAbilityCalcBaseParams calcBaseParams = PatronsMgr.calcPatronsAbilityCalcBaseParams(userPatrons, param);//已经计算过了,不用重复计算
                BigDecimal patronsAddAbility = calcBeautyRelationPatronsAddAbilityIncludePeerless(userPatrons, userBeauty, userPatrons.getBaseAbility(), userPatrons.getCalcAbilityParam(), userPatrons.getAbilityAdditionRatio());
                totalAddition = totalAddition.add(patronsAddAbility);
            }
        }
        return totalAddition;
    }

    /**
     * 获取多次出游消耗元宝
     *
     * @param times 已出游次数
     * @param count 待出游次数
     * @return 消耗元宝
     */
    public static int getTravelCost(int times, int count) {
        List<Integer> travelCostParams = StringUtils.stringToIntegerList(GameConfig.BEAUTY_FAVOR_TRAVEL_COST, "\\|");
        if (travelCostParams.size() != 3) {
            return Integer.MAX_VALUE;
        }

        int res = 0;
        int initValue = travelCostParams.get(0); // 初始消耗
        int addValue = travelCostParams.get(1); // 每次递增
        int maxCost = travelCostParams.get(2); // 最大消耗

        int curCost = initValue + addValue * times;
        while (count > 0) {
            if (curCost >= maxCost) { // 已达最大消耗，快速计算，提前退出
                curCost = maxCost;
                res += curCost * count;
                break;
            }
            res += curCost;
            curCost += addValue;
            count--;
        }

        return res;
    }
}
